﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Media;
using LukasKopenec.LocalizationSupport;
using Notoric.Model.Packaging;

namespace Notoric.ViewModel.Elements
{
    /// <summary>
    /// Adapts a <see cref="LinearCompositionViewPart"/> to a Windows Presentation Foundation View.
    /// </summary>
    public class LinearCompositionView : ViewModelElement, IProjectExplorerItem
    {
        #region Constructors

        /// <summary>
        /// Creates a new <see cref="LinearCompositionView"/> instance.
        /// </summary>
        /// <param name="adaptedPart">
        /// <para>
        /// Type: <see cref="LinearCompositionViewPart"/>
        /// </para>
        /// <para>
        /// The adapted linear composition view package part.
        /// </para>
        /// </param>
        /// <param name="owner">
        /// <para>
        /// Type: <see cref="Composition"/>
        /// </para>
        /// <para>
        /// The composition that directly owns this linear view.
        /// </para>
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Any of the arguments is <see langword="null"/>.
        /// </exception>
        public LinearCompositionView(LinearCompositionViewPart adaptedPart, Composition owner)
            : base(adaptedPart, owner, new Commanding.CommandBase.CommandStack(), new Commanding.CommandBase.CommandStack())
        {
            projectExplorerHelper = new Internal.ProjectExplorerItemHelper(owner, this);
            projectExplorerHelper.PropertyChanged += new PropertyChangedEventHandler(projectExplorerHelper_PropertyChanged);
        }

        #endregion

        #region ViewModelElement Members

        /// <inheritdoc/>
        public override string ElementNameKey
        {
            get { throw new NotImplementedException(); }
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Occurs when the value of some property of the <see cref="projectExplorerHelper"/> has changed.
        /// </summary>
        /// <remarks>
        /// <b>Operation:</b><br/>
        /// The handler just resends the event via its own <see cref="ViewModelElement.PropertyChanged"/>.
        /// </remarks>
        /// <param name="sender">The object that has sent the event</param>
        /// <param name="e">Event data</param>
        private void projectExplorerHelper_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            RaisePropertyChanged(e);
        }

        #endregion

        #region IProjectExplorerItem Members

        /// <inheritdoc/>
        public ContextMenu ContextMenu
        {
            get { return projectExplorerHelper.ContextMenu; }
        }

        /// <inheritdoc/>
        public string DisplayName
        {
            get
            {
                return Name;
            }
        }

        /// <inheritdoc/>
        public ImageSource Icon
        {
            get { return projectExplorerHelper.Icon; }
        }

        /// <inheritdoc/>
        public bool IsExpanded
        {
            get
            {
                return projectExplorerHelper.IsExpanded;
            }
            set
            {
                projectExplorerHelper.IsExpanded = value;
            }
        }

        /// <inheritdoc/>
        public bool IsInEditMode
        {
            get { return projectExplorerHelper.IsInEditMode; }
            set { projectExplorerHelper.IsInEditMode = value; }
        }

        /// <inheritdoc/>
        public bool IsSelected
        {
            get
            {
                return projectExplorerHelper.IsSelected;
            }
            set
            {
                projectExplorerHelper.IsSelected = value;
            }
        }

        /// <inheritdoc/>
        public string Name
        {
            get { return (string)LocalizationManager.GetValue("ProjectExplorer.Labels.LinearCompositionView"); }
            set { throw new NotImplementedException(); }
        }

        /// <inheritdoc/>
        public IProjectExplorerItem Parent
        {
            get { return projectExplorerHelper.Parent; }
            set { projectExplorerHelper.Parent = value; }
        }

        /// <inheritdoc/>
        public ObservableCollection<IProjectExplorerItem> Children
        {
            get { return projectExplorerHelper.Children; }
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets the music content of this linear composition view.
        /// </summary>
        /// <value>
        /// <para>
        /// Type: <see cref="MusicSection"/>
        /// </para>
        /// <para>
        /// The music section that holds the data of the linear composition view.
        /// </para>
        /// </value>
        public MusicSection Content
        {
            get 
            {
                if (content == null)
                    content = new MusicSection((Model.Elements.MusicSectionElement)AdaptedElement, this);
                return content; 
            }
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds the key of a user-friendly name of this element.
        /// </summary>
        private const string elementNameKey = "ViewModel.ElementNames.LinearCompositonView";
        /// <summary>
        /// Holds the value of the <see cref="Content"/> property.
        /// </summary>
        private MusicSection content;
        /// <summary>
        /// Holds the project explorer helper.
        /// </summary>
        private Internal.ProjectExplorerItemHelper projectExplorerHelper;

        #endregion
    }
}
